package com.eastcom.common.util;

import java.io.InputStream;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XmlBuilder {

	private XmlParserUtil parser=null;
	
	private String filePath=null;
	
	public XmlBuilder(InputStream is) throws Exception{
		this.parser=new XmlParserUtil(is);
	}
	
	public XmlBuilder(String filePath) throws Exception{
		this.filePath=filePath;
		this.parser=new XmlParserUtil(filePath);
	}
	
	public void updateTextNodeValueByParentNodeName(String parentNodeName,Map<String,String> textValues) throws Exception{
		if(textValues==null||textValues.isEmpty())
			return;
		
		List<Element> elements=this.parser.getTargetNodesByNodeName(parentNodeName, null);
		
		if(elements!=null){
			for(Element element:elements)
			    this.updateTextNodeValueByParentNode(element, textValues);
			
		    this.flush();
		}
	}
	
	public void updateTextNodeValueByParentNodePath(String parentNodePath,Map<String,String> textValues) throws Exception{
		if(textValues==null||textValues.isEmpty())
			return;
		
		Element[] elements=this.parser.getTargetNodesByParamName(parentNodePath, null);
		
		if(elements!=null&&elements.length>0){
			for(Element element:elements)
			    this.updateTextNodeValueByParentNode(element, textValues);
			
		    this.flush();
		}
	}
	
	public void updateTextNodeValueByParentNodeNameUnderRootNode(String parentNodeName,Map<String,String> textValues) throws Exception{
		if(textValues==null||textValues.isEmpty())
			return;
		
		List<Element> elements=this.parser.getChildNodesOfFirstLevelByNodeName(parentNodeName, null);
		if(elements!=null&&!elements.isEmpty()){
			this.updateTextNodeValueByParentNode(elements.get(0), textValues);
			this.flush();
		}
	}
	
	public void appendNodesUnderParentNode(String parentNodePath,List<Element> appendNodes) throws Exception{
		if(appendNodes==null||appendNodes.isEmpty())
			return;
		
		Element[] elements=this.parser.getTargetNodesByParamName(parentNodePath, null);
		if(elements!=null&&elements.length>0){
			for(Element element:elements)
				this.appendNodesOfParentNode(element, appendNodes);
			
			this.flush();
		}
	}
	
	public void replaceNode(Element parentNode,List<Element> replcaeNodes){
		
	}
	
	private void appendNodesOfParentNode(Element parentNode,List<Element> appendNodes){
		Iterator it=appendNodes.iterator();
		
		while(it.hasNext())
			parentNode.appendChild((Node) it.next());
		
	}
	
	private void updateTextNodeValueByParentNode(Element parentNode,Map<String,String> textValues){
		if(parentNode==null||!parentNode.hasChildNodes()||textValues==null||textValues.isEmpty())
			return;
		
		NodeList nodeLst=parentNode.getChildNodes();
		Node newTextNode=null;
		for(int i=0;i<nodeLst.getLength();i++){
			if(nodeLst.item(i).getNodeType()==Node.TEXT_NODE)
				continue;
			
			Element child=(Element) nodeLst.item(i);
			if(!textValues.containsKey(child.getNodeName()))
				continue;
			
			newTextNode=parser.getDoc().createTextNode(textValues.get(child.getNodeName()));
			child.replaceChild(newTextNode, child.getFirstChild());
		}

	}
	
	private void flush() throws Exception{
		TransformerFactory tFactory=TransformerFactory.newInstance();
		Transformer transformer=tFactory.newTransformer();
		
		transformer.setOutputProperty("encoding", "UTF-8");
		DOMSource  source= new DOMSource(parser.getDoc());
		StreamResult result= new StreamResult(filePath);
		transformer.transform(source,result);
	}
	
	public static void main(String[] args){
		try {
			XmlBuilder builder=new XmlBuilder("E:/SQYWZCZB.xml");
			Map map=new HashMap();
			map.put("nativePointDemarcationCount","6");
			map.put("nativeNormalDay","6");
			map.put("nativeUrgentDay","6");
			
			//builder.updateTextNodeValueByParentNodeName("common-config", map);
			builder.updateTextNodeValueByParentNodeNameUnderRootNode("common-config", map);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}
